import React, { useState, useEffect } from 'react';
import { connect, Dispatch } from 'umi';
import { message } from 'antd';
import { PageContainer } from '@ant-design/pro-layout';
import ProCard from '@ant-design/pro-card';
import { ROLE_LIST, ROLE_ADD, ROLE_UPDATE, ROLE_DELETE, MENU_TREE, GRANT_MENU, API_TREE, GRANT_API, 
  ROLE_UNMOUNT, ROLE_USER } from '@/actions/role';
import AGrid, { AGridButtonCallBackModel } from '@/components/SelfComp/AGrid';
import AButton from '@/components/SelfComp/AButton';
import { ConnectState } from '@/models/connect';
import { DataItem, FlagEnum } from '@/types/global';
import { RoleItem, GrantTreeData, GrantItem } from '@/types/role';
import { UserItem } from '@/types/user';
import { RoleQueryForm, AddRoleModal, UpdateRoleModal, GrantAuthModal, ViewUserDrawer } from './components';
// import AddRoleModal from './components/AddRoleModal';
// import UpdateRoleModal from './components/UpdateRoleModal';
// import GrantAuthModal from './components/GrantAuthModal';

interface RoleListProps {
  dispatch: Dispatch;
  roleList: RoleItem[],
  total: number,
  loading: boolean;
  pageSize: number;
  addLoading: boolean;
  updateLoading: boolean;
  previewMenuLoading: boolean;
  grantMenuLoading: boolean;
  previewApiLoading: boolean;
  grantApiLoading: boolean;
  previewUserLoading: boolean;
  userStatusData: DataItem[];
}

const EMPTY: RoleItem = {
  roleId: '',
  roleCode: '',
  roleName: '',
  roleDesc: '',
}

const EMPTY_TREE: GrantTreeData = {
  roleId: '',
  grantKeys: [],
  treeItems: [],
}

const RoleList: React.FC<RoleListProps> = (props) => {
  // 新增弹窗
  const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
  const [roleFormData, setRoleFormData] = useState<RoleItem>(EMPTY);
  const [updateModalVisible, setUpdateModalVisible] = useState<boolean>(false);
  const [selectedRows, setSelectedRows] = useState<RoleItem[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [queryParam, setQueryParam] = useState<RoleItem>();
  // 默认为10
  const [pageSize, setPageSize] = useState<number>(10);
  const [roleMenuModalVisible, setRoleMenuModalVisible] = useState<boolean>(false);
  const [authTreeData, setAuthTreeData] = useState<GrantTreeData>(EMPTY_TREE);
  const [roleApiModalVisible, setRoleApiModalVisible] = useState<boolean>(false);
  const [apiTreeData, setApiTreeData] = useState<GrantTreeData>(EMPTY_TREE);
  const [flag, setFlag] = useState<FlagEnum>('edit');
  // 角色关联用户
  const [viewDrawerVisible, setViewDrawerVisible] = useState<boolean>(false);
  const [userList, setUserList] = useState<UserItem[]>([]);

  useEffect(() => {
    console.info('RoleList.useEffect');
    // 查询本页面需所有参数
    const { dispatch } = props;
    fetchAllRole(1, pageSize, queryParam);
    return () => {
      dispatch(ROLE_UNMOUNT({}));
    }
  }, []);

  const columns = [
    {
      title: '角色编码',
      dataIndex: 'roleCode',
      width: 150
    },
    {
      title: '角色名称',
      dataIndex: 'roleName',
      width: 200
    },
    {
      title: '角色描述',
      dataIndex: 'roleDesc',
    }
  ];

  /**
   * 打开角色新增窗口
   */
  const openAddRoleModal = () => {
    setAddModalVisible(true);
  }

  /**
   * 修改角色，打开角色修改窗口
   */
  const openUpdateRoleModal = (records: RoleItem[], flag: FlagEnum) => {
    // 表格选中内容
    // console.info('openUpdateRoleModal');
    console.info(records);
    const row = records[0];
    // console.info(roleFormData);
    setRoleFormData(row);
    setFlag(flag);
    setUpdateModalVisible(true);
  }

  const handleAddModalOk = async (record: RoleItem) => {
    // console.log(record);
    const { dispatch } = props;
    const res = await dispatch(ROLE_ADD(record));
    console.info(res);
    if (res) {
      setAddModalVisible(false);
      const { pageSize } = props;
      fetchAllRole(1, pageSize, queryParam);
    }
  }

  const handleAddModalCancel = () => {
    setAddModalVisible(false);
  };

  const handleUpdateModalOk = async (record: RoleItem) => {
    // console.log('handleUpdateModalOk');
    // console.log(record);
    if (flag === 'edit') {
      const { dispatch } = props;
      const res = await dispatch(ROLE_UPDATE(record));
      console.info(res);
      if (res) {
        setRoleFormData(EMPTY);
        setUpdateModalVisible(false);
        const { pageSize } = props;
        fetchAllRole(1, pageSize, queryParam);
      }
    } else {
      setRoleFormData(EMPTY);
      setUpdateModalVisible(false);
    }
  }

  const handleUpdateModalCancel = () => {
    setRoleFormData(EMPTY);
    setUpdateModalVisible(false);
  }

  const deleteRoles = async (keys:  React.Key[]) => {
    const { dispatch } = props;
    const res = await dispatch(ROLE_DELETE(keys));
    if (res) {
      const { pageSize } = props;
      fetchAllRole(1, pageSize, queryParam);
    }
  }

  /**
   * 根据条件分页查询表格数据
   * @param {*} record 条件
   */
  const handleFetchRole = (record: RoleItem) => {
    console.log(record);
    const queryParam = {
      ...record
    };
    // 查询条件保存起来，方便点击页码时使用
    setQueryParam(queryParam);
    fetchAllRole(1, pageSize, queryParam);
  }

  /**
   * 页码改变的回调，参数是改变后的页码及每页条数
   * @param page 改变后的页码，上送服务器端
   * @param pageSize 每页数据条数
   */
  const onPageNumAndSizeChange = (pageNum: number, pageSize: number) => {
    console.log(pageNum, pageSize);
    setPageSize(pageSize);
    fetchAllRole(pageNum, pageSize, queryParam);
  };

  /**
   * 分页查询角色信息
   * @param {*} pageSize 每页记录条数
   * @param {*} pageNum 页码
   */
  const fetchAllRole = (pageNum: number, pageSize: number, queryParam?: RoleItem) => {
    const { dispatch } = props;
    dispatch(ROLE_LIST({
      ...queryParam,
      pageSize,
      pageNum
    }));
  }

  /**
   * 处理按钮点击回调事件
   * @param {*} payload 数据包
   */
  const handleBtnCallBack = (callBackModel: AGridButtonCallBackModel<RoleItem>) => {
    // btn 按钮
    // keys 表格勾选数组
    const { code, keys } = callBackModel;
    // 新增
    if (code === 'add') {
      openAddRoleModal();
      return;
    }
    // 修改
    if (code === 'edit') {
      const { rows } = callBackModel;
      openUpdateRoleModal(rows, 'edit');
      return;
    }
    // 删除
    if (code === 'delete') {
      // 调用删除服务，删除勾选数据
      console.info(keys);
      deleteRoles(keys);
      return;
    }
    // 查看
    if (code === 'view') {
      const { rows } = callBackModel;
      openUpdateRoleModal(rows, 'view');
      return;
    }
  }

  /**
   * 表格勾选回调函数
   * @param {*} rows 表格选中数据集合
   */
  const onSelectRow = (keys: React.Key[], rows: RoleItem[]) => {
    setSelectedRows(rows);
    setSelectedRowKeys(keys);
  };

  /**
   * 工具栏左边的按钮
   * @returns 按钮集合
   */
  const renderLeftButton = () => {
    const { previewMenuLoading, previewApiLoading, previewUserLoading } = props;
    return (
      <>
        <AButton code='roleUser' pageCode='role-list' name='角色关联用户' onClick={openViewUserDrawer} loading={previewUserLoading} />
        <AButton danger code='grantMenu' pageCode='role-list' name='菜单权限分配' onClick={openRoleAuthModal} loading={previewMenuLoading} />
        <AButton danger code='grantApi' pageCode='role-list' name='接口权限分配' onClick={openRoleApiModal} loading={previewApiLoading} />
      </>
    );
  }

  /**
   * 角色授权，打开角色授权窗口
   */
  const openRoleAuthModal = async () => {
    // 表格选中内容
    // console.info('openRoleAuthModal');
    if (selectedRowKeys.length === 0) {
      message.warn('请先选择一条数据!');
      return;
    }
    if (selectedRowKeys.length > 1) {
      message.warn('只能选择一条数据!');
      return;
    }
    // 获取角色id
    const roleId = selectedRowKeys[0];
    // console.info('roleId', roleId);
    const { dispatch } = props;
    const res = await dispatch(MENU_TREE({
      roleId
    }));
    // console.info(res);
    if (res) {
      // 查询菜单权限树，并根据勾选角色ID对应已分配的权限
      // 这里试试dispatch的回调方法
      // 只有查询成功才会弹窗
      const { result } = res;
      const { grantKeys, menuTree } = result;
      const authTreeData: GrantTreeData = {
        roleId,
        grantKeys,
        treeItems: menuTree
      };
      setAuthTreeData(authTreeData);
      setRoleMenuModalVisible(true);
    }
  }

  /**
   * 角色授权，打开角色授权窗口
   */
  const openRoleApiModal = async () => {
    // 表格选中内容
    // console.info('openRoleApiModal');
    if (selectedRowKeys.length === 0) {
      message.warn('请先选择一条数据!');
      return;
    }
    if (selectedRowKeys.length > 1) {
      message.warn('只能选择一条数据!');
      return;
    }
    // 获取角色id
    const roleId = selectedRowKeys[0];
    // console.info('roleId', roleId);
    const { dispatch } = props;
    const res = await dispatch(API_TREE({
      roleId
    }));
    // console.info(res);
    if (res) {
      // 查询菜单权限树，并根据勾选角色ID对应已分配的权限
      // 这里试试dispatch的回调方法
      // 只有查询成功才会弹窗
      const { result } = res;
      const { grantKeys, apiTree } = result;
      const authTreeData: GrantTreeData = {
        roleId,
        grantKeys,
        treeItems: apiTree
      };
      setApiTreeData(authTreeData);
      setRoleApiModalVisible(true);
    }
  }

  /**
   * 菜单权限授权窗口确认按钮
   * @param {*} record 授权树选中菜单列表
   */
  const handleGrantMenuModalOk = async (record: GrantItem) => {
    // console.log('handleGrantModalOk', record);
    // const { roleId, grantKeys } = record;
    // const value = {
    //   roleId,
    //   menuIds: [...grantKeys]
    // }
    const { dispatch } = props;
    const res = await dispatch(GRANT_MENU(record));
    if (res) {
      setAuthTreeData(EMPTY_TREE);
      setRoleMenuModalVisible(false);
      setSelectedRowKeys([]);
    }
  }

  const handleGrantMenuModalCancel = () => {
    // console.log('handleGrantModalCancel');
    setAuthTreeData(EMPTY_TREE);
    setRoleMenuModalVisible(false);
  }

  /**
   * 授权窗口确认按钮
   * @param {*} record 授权树选中菜单列表
   */
  const handleGrantApiModalOk = async (record: GrantItem) => {
    // console.log('handleGrantModalOk', record);
    // const { roleId, grantKeys } = record;
    // const value = {
    //   roleId,
    //   menuIds: [...grantKeys]
    // }
    const { dispatch } = props;
    const res = await dispatch(GRANT_API(record));
    if (res) {
      setApiTreeData(EMPTY_TREE);
      setRoleApiModalVisible(false);
      setSelectedRowKeys([]);
    }
  }

  const handleGrantApiModalCancel = () => {
    // console.log('handleGrantModalCancel');
    setApiTreeData(EMPTY_TREE);
    setRoleApiModalVisible(false);
  }

  const openViewUserDrawer = async () => {
    // 表格选中内容
    console.info('openViewUserDrawer');
    if (selectedRowKeys.length === 0) {
      message.warn('请先选择一条数据!');
      return;
    }
    if (selectedRowKeys.length > 1) {
      message.warn('只能选择一条数据!');
      return;
    }
    const roleId = selectedRowKeys[0];
    const roleItem = selectedRows[0];
    // console.info('roleId', roleId);
    const { dispatch } = props;
    const res = await dispatch(ROLE_USER({
      roleId
    }));
    // console.info(res);
    if (res) {
      const { result } = res;
      console.info(result);
      const { userList } = result;
      if (userList && userList.length > 0) {
        setRoleFormData(roleItem);
        setUserList(userList);
        setViewDrawerVisible(true);
      } else {
        message.warn('该角色下暂无用户');
      }
    }
  }

  const closeViewDrawer = () => {
    setViewDrawerVisible(false);
  }

  const code = 'role-list';
  const { roleList, loading, total, addLoading, updateLoading, grantMenuLoading, grantApiLoading, userStatusData } = props;
  const rowKey = (record: RoleItem) => record.roleId;
  const pkField = 'roleId';
  console.info(columns);
  console.info(Array.isArray(columns));

  return (
    <PageContainer>
      <ProCard title='角色列表' headerBordered>
        <RoleQueryForm colon={false} onSubmit={handleFetchRole} loading={loading}/>
        <AGrid
          code={code}
          btnCallBack={handleBtnCallBack}
          delConfirmMsg='确定删除选中记录？若有用户已分配该角色，将一并删除！'
          renderLeftButton={renderLeftButton}
          columns={columns}
          rowKey={rowKey}
          pkField={pkField}
          dataSource={roleList}
          loading={loading}
          total={total}
          onSelectRow={onSelectRow}
          onPageNumAndSizeChange={onPageNumAndSizeChange}
        />
      </ProCard>
      {
        !addModalVisible ? null :
        <AddRoleModal
          colon={false}
          modalTitle='新增角色'
          modalWidth={1000}
          modalVisible={addModalVisible}
          loading={addLoading}
          onHandlerOK={handleAddModalOk}
          onHandlerCancel={handleAddModalCancel}
        />
      }
      {
        !updateModalVisible ? null :
        <UpdateRoleModal
          colon={false}
          modalTitle=''
          modalWidth={1000}
          modalVisible={updateModalVisible}
          flag={flag}
          loading={updateLoading}
          formData={roleFormData}
          onHandlerOK={handleUpdateModalOk}
          onHandlerCancel={handleUpdateModalCancel}
        />
      }
      {
        !roleMenuModalVisible ? null :
        <GrantAuthModal
          colon={false}
          modalTitle='分配菜单权限'
          modalWidth={600}
          modalVisible={roleMenuModalVisible}
          flag={flag}
          loading={grantMenuLoading}
          formData={authTreeData}
          onHandlerOK={handleGrantMenuModalOk}
          onHandlerCancel={handleGrantMenuModalCancel}
        />
      }{
        !roleApiModalVisible ? null :
        <GrantAuthModal
          colon={false}
          modalTitle='分配接口权限'
          modalWidth={600}
          modalVisible={roleApiModalVisible}
          flag={flag}
          loading={grantApiLoading}
          formData={apiTreeData}
          onHandlerOK={handleGrantApiModalOk}
          onHandlerCancel={handleGrantApiModalCancel}
        />
      }
      {
        !viewDrawerVisible ? null :
        <ViewUserDrawer
          drawerVisible={viewDrawerVisible}
          drawerTitle='已分配的用户列表'
          drawerWidth={1000}
          colon={false}
          loading={false}
          userList={userList}
          formData={roleFormData}
          userStatusData={userStatusData}
          onHandlerCancel={closeViewDrawer}
        />
      }
    </PageContainer>
  );
}

export default connect(({ roles: {rows, ...res}, users: { statusData }, loading }: ConnectState) => ({
  ...res,
  userStatusData: statusData,
  roleList: rows,
  loading: loading.effects['roles/fetchAllRole'],
  addLoading: loading.effects['roles/addRole'],
  updateLoading: loading.effects['roles/updateRole'],
  previewMenuLoading: loading.effects['roles/fetchMenuTreeByRole'],
  grantMenuLoading: loading.effects['roles/grantMenus'],
  previewApiLoading: loading.effects['roles/fetchApiTreeByRole'],
  grantApiLoading: loading.effects['roles/grantApis'],
  previewUserLoading: loading.effects['roles/fetchUsersByRole'],
}))(RoleList);